Recompose patterns
1. Loading status
常规做法: 根据 data.loading来显示 Loading 组件
1 | const Component = props => { |
Recompose 有一个工具函数branch()
,可以基于其中检测函数(test)的结果来组合不同的 Hoc, 可以和另一个 Recompose方法renderComponent()
,联合使用.所以可以说:”如果处于 loading 状态, 就渲染LoadingPlaceholder
而不是默认要展示内容的组件”,实例如下:
Recompose loading
1 | import { propType } from 'graphql-anywhere' |
注意事项:
Loading
只有才查询的第一次才会为真. 如果使用options.notifyOnNetworkStatusChange
,可以用data.networkStatus
字段来跟踪其他的 loading 状态.模式和上面的一样
2. 处理错误
和 loadingStatus 的方法类似,如果出了问题,我们想显示一个不同的组件,或者允许用户重新加载(refetch()
). 使用withProps()
方法直接用 props 传递 refetch 方法. 这里的方法是通用的, 没有和任何的组件耦合.
1 | const renderForError = (component, propName = "data") => |
3. 查询周期
在有些用例中,需要在查询完成之后执行一些其他工作. 上面的实例中,没有错误出现,没有 loading 的时候会渲染默认组件.
但是组件是无状态的,没有生命周期函数的钩子(hook).如果还要使用额外的周期功能,可以用 Recompose 的lifecycle()
函数来补救
1 | const execAtMount = lifecycle({ |
上面的实例,如果我们需要在组件加载时做些额外的工作,可以这么操作
来看看另一个更为复杂的用例, 例如我正在使用re-select
,可以让用户从查询的结果中挑选部分内容. 想一直显示 re-select,它有自己的 loading state indicator.接着在查询成功以后自动的选择预定义的选项.
如果使用默认的访问策略(fetchPolicy)让每个组件都获取数据,只有一个特别的地方需要处理. 需要留意的地方:要查询的数据已经在 cache 中的时候,就会跳过 loading state
. 这种情况下,我们需要在组件加载时处理networkStatus===7
.
同时还要使用recompose的withState()
方法保存选项值. 在这个例子中我们保持默认的data
属性不变.
1 | const DEFAULT_PICK = "orange"; |
4. 控制轮询
这个例子是一个显示 meteor框架中的数据库迁移状态的组件:migrations panel.并不总是运行迁移,所以设置轮询为30s,就比较好.但是如果在数据库迁移过程中,我们需要竟可能快的显示进度.
解决问题的关键是 react-apollo 的
options
参数, 这个参数可以是一个依赖于 React props 为参数的函数.(options
参数描述了查询自身的参数, 和 React 的 props 是不同的). 我们可以根据传递到graphql 组件的 props,通过使用recompose的withState()
函数设定轮询的周期,并且使用componentWillReceiveProps
React的生命周期函数来查看从 GraphQL获取的数据,并作出相应的调整.
基本的流程就是,默认30秒查询一次数据库迁移状态的数据,如果数据存在时,就立刻把查询的轮询时间改为0.5s.
代码如下:
1 | import { graphql } from "react-apollo"; |
但是这个轮询似乎还有缺陷, 如果在30s轮询周期内, 数据库迁移完成了,我们就看不到任何的提示. 或许要使用 subscription方法.